package com.chuangke.flow.util;

import com.chuangke.common.exception.ChuangkeException;
import com.chuangke.common.idgen.IdManager;
import com.chuangke.common.utils.SecurityUtils;
import com.chuangke.common.utils.SpringContextUtil;
import com.chuangke.flow.constant.FlowConstant;
import com.chuangke.flow.dao.FlowHiTaskLogDao;
import com.chuangke.flow.domain.FlowAuditResult;
import com.chuangke.flow.domain.FlowHandler;
import com.chuangke.flow.entity.FlowHiTaskLog;
import com.chuangke.flow.entity.FlowRuTask;
import com.chuangke.flow.enums.FlowNodeStatusEnum;
import com.chuangke.flow.service.FlowTaskService;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.collections.CollectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class FlowUtils {

	public static void handleOrder(String service, String method, String businessKey, Map<String, Object> variables) {
		Object obj = null;
		try {
			obj = SpringContextUtil.getBean(Class.forName(service));
			variables = variables== null ? new HashMap<>() : variables ;
			MethodUtils.invokeMethod(obj, method, new Object[] { businessKey, variables });
		} catch (InvocationTargetException e) {
			if (e.getCause() instanceof ChuangkeException) {
				throw (ChuangkeException) e.getCause();
			} else {
				throw new RuntimeException(e);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	public static void handleOrderBatch(String service, String method, List<String> businessKeyList) {
		Object obj = null;
		try {
			obj = SpringContextUtil.getBean(Class.forName(service));
			MethodUtils.invokeMethod(obj, method, new Object[] { businessKeyList });
		} catch (InvocationTargetException e) {
			if (e.getCause() instanceof ChuangkeException) {
				throw (ChuangkeException) e.getCause();
			} else {
				throw new RuntimeException(e);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 审批
	 * @param flowService
	 * @param orderIdList
	 * @param auditType
	 * @param message
	 * @return
	 */
	public static FlowAuditResult audit(FlowTaskService flowService, List<String> orderIdList, String auditType, String message) {
		String auditUser = SecurityUtils.getUserId();

		if (CollectionUtils.isEmpty(orderIdList)) {
			throw new ChuangkeException("请选择数据");
		}

		List<FlowHandler> bbpIdList = orderIdList.stream().map(id -> {
			FlowHandler handler = new FlowHandler();
			handler.setAudit(auditType);
			handler.setBusinessKey(id);
			handler.setUserId(auditUser);
			handler.setMessage(message);
			handler.setSubmitRestrictTaskUser(true);
			return handler;
		}).collect(Collectors.toList());

		FlowAuditResult flowAuditResult = null;
		if (FlowConstant.VAR_AUDIT_OPT_REVOKE.equals(auditType)) {
			flowAuditResult = flowService.revoke(bbpIdList);
		} else {
			flowAuditResult = flowService.complete(bbpIdList);
		}

		return flowAuditResult;
	}

	/**
	 * 任务历史中增加一条任务历史记录任务的开始时间，结束的时候更新这条任务历史，更新结束时间
	 *
	 * @param firstTaskList
	 */
	public static void startTaskInHistory(FlowHiTaskLogDao flowHiTaskLogDao,List<FlowRuTask> firstTaskList) {
		if (CollectionUtils.isEmpty(firstTaskList)) {
			return;
		}

		List<FlowHiTaskLog> hiFirstTaskLogList = firstTaskList.stream().map(ruTask -> {
			FlowHiTaskLog hiTaskLog = FlowModelUtils.convertRHL(ruTask);
			hiTaskLog.taskId(ruTask.getId()).id(IdManager.nextId()).status(FlowNodeStatusEnum.unhandle.getCode())
					.comments("").startAt(new Date());
			return hiTaskLog;
		}).collect(Collectors.toList());

		flowHiTaskLogDao.insertBatchSomeColumn(hiFirstTaskLogList);
	}
}
